
#include <stdlib.h>
#include <string.h>
#include <iostream>
#define MEM_PAGE_SIZE 0x1000

typedef struct mem_node
{
    struct mem_node *next;
    char data[1];
} mem_node_t;

typedef struct mem_pool
{
    int freeSize;
    int blockSize;
    char *freeMem;
    char *mem;
    mem_node_t head[0];
} mem_pool_t;

// blockSize:2,4,8,16,32,64,128,256,512,1024
mem_pool_t *create_mempools(int blockSize)
{
    mem_pool_t *pool = (mem_pool_t *)malloc(sizeof(mem_pool_t));
    memset(pool, 0, sizeof(mem_pool_t));
    if (pool == NULL)
    {
        return NULL;
    }
    pool->blockSize = blockSize;
    pool->freeSize = MEM_PAGE_SIZE / blockSize;
    pool->freeMem = (char *)malloc(MEM_PAGE_SIZE);
    memset(pool->freeMem, 0, MEM_PAGE_SIZE);
    pool->mem = pool->freeMem;
    char *p = pool->freeMem;
    for (int i = 0; i < pool->freeSize; i++)
    {
        *(char **)p = p + blockSize;
        p = p + blockSize;
    }
    *(char **)p = NULL;
    return pool;
}

void destr_mempools(mem_pool_t *pool)
{
    free(pool->mem);
    free(pool);
}

void *alloc_mem(mem_pool_t *pool)
{
    if (!pool || pool->freeSize == 0)
        return NULL;
    pool->freeSize--;
    void *ret = pool->freeMem;
    pool->freeMem = *(char **)ret;
    return ret;
}

void free_mem(mem_pool_t *pool, void *ptr)
{
    if (!pool || !ptr)
        return;
    *(char **)ptr = pool->freeMem;
    pool->freeMem = (char *)ptr;
    pool->freeSize++;
}
using namespace std;
int main()
{
    mem_pool_t *pool = create_mempools(8);
    cout << "pool_ptr:" << (void *)pool->freeMem << "\n";
    void *p1 = alloc_mem(pool);
    cout << "p1:" << p1 << "\n";
    void *p2 = alloc_mem(pool);
    cout << "p2:" << p2 << "\n";
    free_mem(pool, p1);
    void *p3 = alloc_mem(pool);
    cout << "p3:" << p3 << "\n";
    cout << "pool_ptr_size:" << sizeof(p1) << "\n";
    cout << "mem_pool_t size:" << sizeof(mem_pool_t) << "\n";

    destr_mempools(pool);
    return 0;
}